<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.js"></script>
    <style>
        li{list-style: none;}
    </style>
</head>
<body>
    <div id="app">
         <!-- <div>
             <button @click="addEle">新增</button>
             <button @click="delEle">删除</button>
         </div>
         <div>
            <ul>
                <li v-for="(item,index) in list" :key="index">{{item}}</li>
            </ul>
         </div> -->

        <!-- watch监听对象 -->
        
        <div>
            <span>{{zhang.name}}</span>
            <span>{{zhang.age}}</span>
            <span>{{zhang.height}}</span>
            <span>{{zhang.weight}}</span>
        </div>
        <div>
            修改名字: <input type="text" v-model.lazy="zhang.name">
        </div>
        <div>
            修改年龄: <input type="text" v-model.number="zhang.age">
        </div>

    </div>
</body>
<script>
    // watch  侦听器(数据监听)   (被监听的数据发生改变之后 对其他数据造成的影响 => 主动变化)
    // 1. 监听data中数据的变化,并执行对应的回调函数(对应属性的属性值发生改变)  => 更注重自身数据的变化对其他数组造成的影响
    // 2. 支持异步
    // 3. watch在初始化阶段并不执行, 而是在数据改变之后才执行



    // 注意:

    // Vue的响应式
    // Vue的响应式对data中的所有数据配置了拦截器 Object.defineProperty()  => 只要data中的任意属性发生改变 => 都会触发视图更新  (Vue自己内部知道数据变化了 => 咱们只能看见 不知道) 

    // watch监听数组
    // watch => 可以监听数组的变化 =>  Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新/也可以被watch中的侦听器监听到

    // watch监听对象
    // watch在监听data中的属性时,默认是浅层的 => 只监听该属性的值的变化,但是如果属性值是一个对象, 该对象的子属性发生变化时 => 默认无法监听
    
    // 如何让watch监听属性时,开启深度监听? 
    // 给监听的属性配置对象  {handler,deep,immediate}
    // handler => 被监听的属性改变时,处理函数
    // deep    => 开启深度监听 => 可以监听当前属性及其子属性

    // 新的问题 =>  回调函数触发时newVal,oldVal 都引用对象的内存空间 => newVal和oldVal都是通一个值 (只能使用新值 => 没有办法拿到旧值)

    // 解决方法1:
    // 直接监听对象的子属性的改变 => 按需求

    // 解决方法2:
    // 先对被监听的属性(属性值是对象)进行深复制 => 新值, 在监听复制后的数据(新值)的改变


    var vm= new Vue({
        // el:"#app",
        data:{ // data中的数据拦截
            list:[1,4,7,2,5,8,3,6,9],
            zhang:{name:"张三",age:18,height:177,weiht:70},
        },
        methods: {
            addEle(){
                console.log("新增元素");
                var num = Math.round(Math.random()*10);
                // this.list.push(num);   // 影响原数组
                this.list = this.list.concat(num);  // 返回新数组
            },
            delEle(){
                this.list.length--;
                this.$forceUpdate();
            } 
        },
        watch:{
            list:function(newVal,oldVal){
                console.log("数组发生了改变", newVal,oldVal);
            },

            // 监听zhang这个属性,及其子属性的变化(子属性变化->触发回调函数=>等价于zhang变化了) => 
            /* zhang:{
                // 处理函数 => 当被侦听的属性发生改变时,会触发回调函数
                handler:function(newVal,oldVal){
                    console.log("zhang发生了改变", newVal.age,oldVal.age);
                },
                deep:true, // 开启深度监听 => 如果该属性的属性值是一个对象,也会对该对象下子属性进行监听, 如果子属性变化也会触发当前属性的处理函数
            }, */

            "zhang.age":function(newVal,oldVal){
                console.log("zhang的年龄发生了改变", newVal,oldVal);
            },
        }
       
    })

    vm.$mount("#app");

</script>
</html>